מבוא למדעי המחשב תירגול 2: לולאות, קלט, וטיפוסים 1
תוכנייה לולאת while קלט טיפוסי משתנים המרת טיפוסים טיפוס char 2
לולאת while 3
לולאת while קטע קוד מתבצע שוב ושוב כל עוד תנאי מתקיים int number = 40; while(number>0) { printf( %d remain\n,number); number=number-1; } תנאי גוף הלולאה 4
לולאת while תרגיל 1: הדפיסו כמה פעמים ניתן לחלק מספר ב 2 שהתוצאה קטנה או שווה ל 1 לפני 5
לולאת while int number = 128, counter = 0; while(number>1) { } number/=2; counter++; printf( log2(%d)=%d\n,number, counter); תנאי גוף הלולאה מה הבעיה? 6
לולאת while int original_number = 128, counter=0; int number = original_number; while(number>1) { } number/=2; counter++; printf( log2(%d)=%d\n,original_number, counter); תנאי גוף הלולאה 7
קלט 8
- קלט scanf הפונקציה scanf קוראת ערך לתוך משתנה. קריאה פשוטה ל- scanf מתבצעת כך: שורה זאת קוראת ערך לתוך המשתנה x. בדומה ל- printf ניתן לקרוא יותר ממשתנה אחד: int x; scanf("%d", &x); scanf("%d%d", &a, &b); שימו לב לסימן ה-& לפני כל שם משתנה! סימן זה הוא חובה! את הסיבה לכך נבין בתרגולים מתקדמים 9
-scanf קלט לפקודה scanf() יש לציין איזה טיפוס של נתון אנו רוצים לקרוא מהמשתמש: שלם d% או שבר %lf (שימו לב להבדל מ- printf ). כאשר התוכנית מגיעה בזמן ריצה לפקודת,scanf() היא עוצרת ומציגה סמן מהבהב למשתמש. בשלב זה התוכנית מאפשרת למשתמש להקליד את הנתון, וכאשר הוא לוחץ על Enter הנתון שהוא הקליד מועבר לתוכנית. נתון זה מוכנס למשתנה שצוין, ואז התוכנית ממשיכה בריצתה. 10
קלט/פלט תרגיל 2: כתבו תוכנית הקולטת 2 מספרים מהמשתמש ומדפיסה את סכומם #include <stdio.h> int main() { printf( Please enter numbers:\n ); int x=88,y=19; scanf( %d%d, &x, &y); printf( The sum is: %d,x+y); return 0; } פלט: Please enter numbers: קלט: 10 2 פלט: The sum is: 12 11
קלט/פלט - הרחבה כישלון בקריאת הקלט + Input buffer בדיקת קלט EOF 12
כשלון של scanf int main() { int a=-1; scanf( %d, &a); printf( a=%d,a); return 0; } קלט: מה תדפיס התוכנית הבאה? ten 10,a תשובה: 1-=a התוכנית לא הצליחה לקרוא את משהו שהוא לא מספר! 13 כי הכנסנו
ערך החזרה של scanf איך נגלה אם קריאת הקלט הצליחה? תשובה: ע"י בדיקת ערך ההחזרה של.scanf ערך ההחזרה של scanf הוא מספר שלם המייצג את מספר הדגלים (%) ש- scanf הצליחה "לאכול". כלומר, מספר המשתנים ש scanf הצליחה לקלוט. 14
ערך החזרה של scanf אם הקריאה של דגל כלשהו נכשלה, לא יהיה ניסיון להמשיך ולקרוא את שאר הדגלים. דוגמאות לשימוש בערך ההחזרה של :scanf int res = scanf("%d", &x); שמירת הערך השוואת הערך לקבוע &x)==1) 1 if (scanf("%d", 15
scanf בדיקת ערך החזרה int main() { int a=-1,b=-1,c=-1; if(scanf( %d, &a)!=1){ printf( Error in a\n ); return 0; } if(scanf( %d%d, &b, &c)!=2){ printf( Error in b or c\n ); return 0; } } printf( a=%d,b=%d,c=%d, a,b,c); return 0; קלט: 10 twenty 30 פלט Error in b or c 16
בדיקת קלט כאשר אתם משתמשים ב- scanf בתרגילי הבית, עליכם לוודא שהיא הצליחה. ניתן לעשות זאת באמצעות בדיקת ערך ההחזרה שלה: למשל אם היא הייתה אמורה לקלוט 2 מספרים: if(scanf("%d%d",&d,&n)!=2){ printf( Error );... } 17
חוצץ הקלט Buffer) (Input מטרתנו כעת היא להבין כיצד עובדת קליטת קלט בעזרת.scanf לצורך כך, עלינו להכיר מושג חדש: חוצץ הקלט. חוצץ הקלט הוא אזור זיכרון המתוחזק ע"י מערכת ההפעלה. תפקידו הוא לשמור את קלט המשתמש עד אשר הוא נקרא ע"י התוכנית (או עד שהתוכנית מסתיימת) מערכת ההפעלה תפנה למשתמש (תחכה לקלט) רק כאשר החוצץ ריק. בתחילת התוכנית החוצץ תמיד ריק. 18
מה קורה אם נקליד שני מספרים? 10 9 משתמש Input Buffer מערכת הפעלה 10 9 scanf( %d,&num1);... scanf( %d,&num2); תוכנית 19
קלט שגוי היות כאשר החוצץיש ברגע וחוצץ אינו כאשר נתונים הקלט ריק! הנתון ריק, אולם שהמשתמש בחוצץ, הבא מקיש מערכת בתור קוראים scanf אינו ממנו,ENTER ההפעלה מדלגת את מתאים על פונה התווים הנתונים לטיפוס רווחים ל- stdin נכנסים לפי לבנים המבוקש לחוצץ הסדר (במקרה (רווח, ככל הזה בחוצץ) המקלדת) לקבלת קלט טאב, הקריאהוכו'), נכשלת פרט שניתן, כל (התוכןעוד למקרים שלהם (כולל שנקלטים המשתנה מתאימים תווים נשאר ה- ENTER!)או לטיפוס כשהיה מחרוזות המבוקש והנתון (c% או נשארs %) 10 a6 משתמש Input Buffer מערכת הפעלה 10 a6 scanf( %d,&num1);... scanf( %d,&num2); תוכנית 20
התקני הקלט והפלט הסטנדרטיים באופן רגיל :(scanf) מגיע מהמקלדת :(printf) מגיע למסך קלט סטנדרטי פלט סטנדרטי עם redirection קלט סטנדרטי פלט סטנדרטי (כמו שנלמד בתרגול 1) hw0q1.exe < input.txt > output.txt input.txt מהקובץ :(scanf) :(printf) לקובץ.output.txt התוכנית איננה יודעת בזמן הרצתה לאן מקושרים הקלט והפלט הסטנדרטים. זהו תפקידה של מערכת ההפעלה. 21
קריאה מקובץ והקבוע EOF כאשר קוראים מקובץ, הקלט יכול להגמר (לא יכול לקרות בקלט ממקלדת). במקרה כזה, scanf מחזירה את הקבוע.(End Of File) EOF if(scanf("%d%d",&d,&n)==eof){ printf( No input );... } כאשר הקלט מגיע מהמקלדת, ניתן להכניס סימן EOF מלאכותי בקלט באמצעות לחיצה על Ctrl+Z במקלדת Ctrl+D) במאכ). שימו לב! יש ללחוץ על Ctrl+Z בשורה חדשה במסך על מנת שיקלט.EOF 22
טיפוסי משתנים 23
טיפוסי משתנים אם משתנה הוא רצף סיביות בזיכרון, אזי טיפוס המשתנה היא הדרך לפרש את הסיביות (byte) לדוגמא: בית 11111111 11111111 11111111 11111111 עבור unsigned int מתפרש כ " " " עבור int מתפרש כ " 24
משתנים וטיפוסי משתנים ישנם טיפוסים רבים בשפת C: שלמים: char, short, int, long, long long חיוביים: etc. unsigned char, unsigned short, שברים: float, double, long double טיפוסים שונים תופסים כמות זיכרון שונה. 25
משתנים וטיפוסי משתנים Type min max precision Size in memory* int -2147483648 2147483647 1 4 unsigned 0 4294967295 1 4 double -1.79e10 308 1.79e10 308 2.2*10-308 (depend on number) 8 long long -2 63 2 63-1 1 8 char -128 127 1 1 הגודל המדוייק תלוי בחומרה ובמערכת ההפעלה הדיוק של שברים תלוי בערכם המדוייק הדיוק קטן) (ככול שהערך יותר גדול, 26
משתנים וטיפוסים תרגיל 2: קלטו 2 מספרים שלמים base ו,exp base exp (חזקה) התוכנית צריכה לטפל בתוצאות עד וחשבו 10 15 27
משתנים וטיפוסים long long pow=1; int base, exp; scanf( %d%d, &base, &exp); while( exp>0 ) { pow*=base; exp--; } printf( pow=%lld\n,pow); 28
משתנים וטיפוסים long long pow=1; int base, exp; scanf( %d%d, &base, &exp); while( exp>0 ) { pow*=base; exp--; } :long long printf( pow=%lld\n,pow); :int תוצאה כאשר pow מטיפוס תוצאה כאשר pow מטיפוס 29
Casting המרה - 30
המרת משתנים אוטומטית בשפת C ישנן פעולות רבות המערבות שני איברים: a>b a+=b a=b a*b a+b אם האיברים אינם מאותו הטיפוס, מתבצעת המרה אוטומטית. עבור פעולות השמה, הערך בצדו הימני של האופרטור מומר לטיפוסו של המשתנה שלתוכו כותבים. לכל יתר האופרטורים, הטיפוס עם תחום הייצוג הקטן יותר מומר לזה עם תחום הייצוג הגדול יותר, לפי הסדר הבא: char short int long float double long double 31
המרה אוטומטית סוף הסיפור? המרה אוטומטית אינה מתבצעת כשמשתמשים ב-() printf. במקרה זה יש לבצע המרה מכוונת. ומה לגבי התוכנית הבאה? int num1 = 100000, num2 = 500000; double product = num1 * num2; מדוע זה עלול לא לעבוד? 32
המרה מכוונת (casting) המרת ערך כלשהו לטיפוס אחר נעשית על ידי כתיבת שם הטיפוס החדש בסוגריים, לפני הערך עצמו. למשל : int x = 2; printf("%f", (double)x ); double d = (double)3 / 2; מחזיר את ערכו של double כטיפוס x פעולת ההמרה לוקחת את הערך הנתון, ומחזירה עותק שלו מהטיפוס החדש (היא אינה משנה את הערך המקורי!). בדוגמה למעלה, x עצמו איננו משתנה כתוצאה מהפעולה. 33
דוגמאות ל- Casting int cake_num = 5, children = 3; double cake_per_child; כמות העוגה שיש לכל ילד: cake_per_child = (double)cake_num / children ; cake_per_child = cake_num / (double)children ; cake_per_child = (double)(cake_num / children); מה תהיה התוצאה? 34
טיפוסי משתנים - סיכום 0,1,435,-99 טיפוסים שונים :int מספרים שלמים, למשל: למשל: וכו'. -324.3 0.0, 1.0, 1.2, וכו'. float, unsigned, long, long long, char, bool :double שברים, ועוד המון: המרה בין טיפוסים מפורשת,(double) או אוטומטית ועוד קלט ופלט: %d, %f, %lf 35
טיפוס char 36
לפענח char קצת אחרת... משתנה מסוג char (בית אחד). יכול לשמור אחד מ- 256 ערכים שונים A ישנה טבלה סטנדרטית (ASCII) להמרה בין 256 ערכים מספריים, לבין 256 תווים שונים. למשל, = 66 B A = 65, וכו'. כתיבת התו בין גרשיים נותנת את הערך המספרי שלו, לדוגמה: שם הטיפוס,char הוא קיצור ל- character זה. ורומז על שימוש 37
טבלת :ASCII ממספרים לתווים רווח הוא מס' 32 )ישנם תווים כגון lf, cr, eof שאינם ניתנים להדפסה ומייצגים תזוזות של הסמן או הגעה לסוף קלט וכד'( רק חצי מהטבלה מופיע כאן. כדי לראות את הטבלה המלאה חפשו Extended ASCII Table 38 מבוא למדעי המחשב מ' - תירגול 2
תכונות הטבלה הערכים המתאימים לתווים '9' '0' הם רציפים, ולפי סדר הספרות. הערכים המתאימים לתווים 'a'..'z' ולפי סדר הא"ב הרגיל. רציפים, כך גם הערכים המתאימים לתווים.'A' 'Z' 39
תווים תרגיל 3 א': כתבו תכנית המקבלת כקלט תו בודד ומדפיסה אותו ואת ערך ה- ASCII שלו. char c = 0; scanf(" %c", &c); printf("numeric value=%d, character=%c\n", c,c); הרווח כאן חשוב- פירושו שיש להתעלם מרווחים וממעברי שורה המופיעים בתחילת המשפט (התו שיכנס ל- c הוא התו הראשון שאינו רווח) 40
תווים 3 ב': כתבו תכנית הקולטת רצף תווים עד שהתקבל ומדפיסה כל תו ואת ערך ה- ASCII שלו (כולל הנקודה). תרגיל התו., char c = 0; scanf(" %c", &c); while (c!= '.') { printf("numeric value=%d, character=%c\n", c,c); scanf(" %c", &c); } printf("numeric value=%d, character=%c\n", c,c); הפלט יופיע רק לאחר הקשת.ENTER 41
תווים תרגיל 4: כתבו תכנית המקבלת כקלט אות קטנה בשפה האנגלית ומדפיסה אותה כאות גדולה. 42
תווים תרגיל 4: כתבו תכנית המקבלת כקלט אות קטנה בשפה האנגלית ומדפיסה אותה כאות גדולה. char c; scanf(" %c", &c); c = (c- a )+ A ; printf("%c", c); 43
תווים תרגיל 5: כתבו תכנית המקבלת כקלט אות קטנה בשפה האנגלית ומדפיסה את האות העוקבת לה (העוקבת של z היא a). 44
תווים לפני main תרגיל 5: כתבו תכנית המקבלת כקלט אות קטנה בשפה האנגלית ומדפיסה את האות העוקבת לה (העוקבת של z היא a). #define NUM_LETTERS ( z - a +1) קטע קוד מתוך הפונקציה main char c; scanf(" %c", &c); c = (c- a ); c = (c+1)% NUM_LETTERS; c += a ; 45 printf("%c", c);
תווים תרגיל 6: כתבו מחשבון תכנית המקבלת מספר, פעולת חשבון (חיבור/חיסור/כפל/חילוק) ומספר, מחשבת ומדפיסה את ערך הביטוי. 46
תווים char c = 0; int op1 = 0, op2 = 0, res = 0; scanf( %d %c %d, &op1, &c, &op2); switch(c){ } case + : res = op1+op2; break; case - : res = op1-op2; break; case * : res = op1*op2; break; case / : res = op1/op2; break; default: printf( error: unknown operation ); return 1; printf( %d%c%d=%d\n, op1, c, op2, res); 47
תווים - סיכום הטיפוס char מכיל מספר בין 0 ל 255 מקביל לתווים ע"י טבלת ASCII קבועי תווים ( A ) הדפסה באמצעות,d% c% 48
טיפוסי משתנים - תרגילים 49
מהו ערכו וטיפוסו של הביטוי? ביטוי טיפוס ערך 5-4 int 1 1 / 2 int 0 1 / 2. double 0.5 (double)1 / 2 double 0.5 (double)(1 / 2) double 0.0 'A' + 3 int 'D' (= 68,ONLY if ASCII) 'Z' - 1 int 'Y' (= 89, ONLY if ASCII) 'Z' - 'A' + 'a' int 'z' 'E' + 4*('b'-'c') int 'A' 50
מהו ערכו וטיפוסו של הביטוי? [כאשר יש יותר מביטוי אחד, התיחסו לביטוי הצהוב] char c; int i הניחו שהמשתנים הבאים הוגדרו: תופעות לוואי ערך טיפוס ביטוי c = 'G'; i = 3; (double)i/(c-'e') i = 5.7; i = 5.2; (double)i 51
מהו ערכו וטיפוסו של הביטוי? [כאשר יש יותר מביטוי אחד, התיחסו לביטוי הצהוב] char c; int i הניחו שהמשתנים הבאים הוגדרו: תופעות לוואי ערך טיפוס ביטוי c = 'G'; i = 3; (double)i/(c-'e') double 1.5 c 'G' i 3 i = 5.7; int 5 i 5 i = 5.2; int 5 i 5 (double)i double i אין! בפרט, i לא השתנה! 52
אופרטורים 53
אופרטורים אופרטור הוא פעולה של C, המקבלת ערך יחיד או זוג ערכים, ומחזירה ערך כלשהו. אופרטור אונארי אופרטור בינארי operator) (unary מקבל ערך יחיד. operator) (binary מקבל זוג ערכים. ישנם מספר אופרטורים המשנים את הערכים שהם מקבלים. השפעה זו נקראת תוצאת לוואי (side-effect) של האופרטור. 54
אופרטורים בינאריים פעולות חשבון: a+b a-b a*b a/b a%b השוואות: a==b a!=b a<b a>b a<=b a>=b a && b a b פעולות לוגיות: השמות: a=b a+=b a-=b a*=b a/=b 55
אופרטורים אונאריים -a (double)num מינוס מתמטי: :casting אופרטורי קידום: a++ a-- ++a --a 56
דוגמאות int x = 5, y = 0; x = 5, y = 0 y = -x + x ; y = ++x + 7 ; y = x++ + 3; x = 6, y = 13 x = 7, y = 9 y = ++x + x++ ; מה לדעתכם יקרה פה? 57
דוגמאות int x=0, y=5; while(x++<y){ } printf( %d,x); מה יודפס? int x=0, y=5; while(++x<y){ printf( %d,x); } ומה עכשיו? 58